/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package models;

import config.Models.Conf_Egg;
import db.Redis_Rd;
import db.Redis_W;
import entities.Egg;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import libCore.Util;
import org.json.simple.JSONValue;
import share.KeysDefinition;

/**
 *
 * @author LinhTA
 */
public class U_EggModel implements BaseModel {

    public int uId;

    public U_EggModel(int uid) {
        uId = uid;

    }

    @Override
    public void setDB() {
    }

    @Override
    public void setData(Map<String, String> obj) {
    }

    @Override
    public void getDB(String uid) {
    }

    public static Map<Long, Map<String, Egg>> isNewUser(String uid, String keyEggs, long time) {
        Map<Long, Map<String, Egg>> listEggs = new HashMap<Long, Map<String, Egg>>();
        return listEggs;
    }

    public static Egg defaultEgg() {
        Egg egg = new Egg();

        egg.gold = 10;
        egg.kind = "0001";
        egg.timeBirth = 0;

        return egg;
    }

    public static Map<String, Egg> getDBEggs(String kEggs) {
        Map<String, Egg> eggs = new HashMap<String, Egg>();

        String keyEggs = kEggs;

        // get list egg type
        Set<String> slist = Redis_Rd.getInstance().smember(keyEggs);
        if( slist != null )
        {
            for (int i = 0; i < slist.size(); i++) 
            {
                String keyEggType = slist.toArray()[i].toString();
                Set<String> eggKeys = Redis_Rd.getInstance().smember(keyEggType);
                for( int j = 0; j < eggKeys.size(); ++j )
                {
                    String keyEgg = eggKeys.toArray()[j].toString();
                    String egg = Redis_Rd.getInstance().get(keyEgg);
                    Map<String, Object> data = (HashMap<String, Object>) JSONValue.parse(egg);
                    Egg e = new Egg();
                    e.setData(data);

                    eggs.put(keyEgg, e);
                }
            }
        }
        
        return eggs;
    }
    
    public static Egg getDBEgg(String kEgg) {
        String egg  =   Redis_Rd.getInstance().get(kEgg);
        Map<String, Object> data    =   (HashMap<String, Object>) JSONValue.parse(egg);
        Egg e       =   new Egg();
        e.setData(data);
        
        return e;
    }

    public static Map<String, Egg> getDBEggs(String[] kEggs) {
        Map<String, Egg> eggs = new HashMap<String, Egg>();
        for (String kEgg : kEggs) {
            String egg = Redis_Rd.getInstance().get(kEgg);
            Map<String, Object> data = (HashMap<String, Object>) JSONValue.parse(egg);
            Egg e = new Egg();
            e.setData(data);

            eggs.put(kEgg, e);
        }
        
        return eggs;
    }
    
    public static String addDBEgg(Egg egg) {
        String key      =   KeysDefinition.randomKeySTR();
        
        if (Redis_W.getInstance().set(key, Util.obj2String(egg)) == -1) {
            return "";
        }

        return key;
    }

    public static Map<String, Egg> parseEggs(Map<String, Object> obj) {
        Map<String, Egg> eggs = new HashMap<String, Egg>();

        for (Map.Entry<String, Object> o : obj.entrySet()) {
            String string = o.getKey();
            Object object = o.getValue();

            Egg e = new Egg();
            e.setData(Util.obj2Map(object));
            eggs.put(string, e);
        }

        return eggs;
    }

    public static Map<Long, Map<String, Egg>> parseTimeEggs(Map<String, Egg> obj) {
        Map<Long, Map<String, Egg>> listEggs = new HashMap<Long, Map<String, Egg>>();

        for (Map.Entry<String, Egg> o : obj.entrySet()) {
            String string = o.getKey();
            Egg e = o.getValue();

            Map<String, Egg> eggs = new HashMap<String, Egg>();
            long time = e.timeBirth;
            
            eggs.put(string, e);
            if( listEggs.containsKey(time) )
                listEggs.get( time ).putAll(eggs);
            else 
                listEggs.put(time, eggs);
        }
            
        System.out.println( "parse time eggs: " + listEggs.size() );

        return listEggs;
    }

    public static Map<String, Object> toAMF(Map<String, Egg> eggs) {
        Map<String, Object> data = new HashMap<String, Object>();

        for (Map.Entry<String, Egg> entry : eggs.entrySet()) {
            String string = entry.getKey();
            Egg object = entry.getValue();

            data.put(string, object.toAMF());
        }

        return data;
    }

    public static Map<Long, Map<String, Object>> toTimeAMF(Map<Long, Map<String, Egg>> listEggs) {
        Map<Long, Map<String, Object>> data = new HashMap<Long, Map<String, Object>>();

        for (Map.Entry<Long, Map<String, Egg>> entry : listEggs.entrySet()) {
            Long long1 = entry.getKey();
            Map<String, Egg> map = entry.getValue();

            Map<String, Object> dataEggs = new HashMap<String, Object>();

            for (Map.Entry<String, Egg> e : map.entrySet()) {
                String string = e.getKey();
                Egg object = e.getValue();

                dataEggs.put(string, object.toAMF());
            }

            data.put(long1, dataEggs);

        }


        return data;
    }

    /*
    Add new egg entity to database ( key value )
    */
    public static String addEgg(Conf_Egg confEgg, String kindEgg, long birh) {
        String key = KeysDefinition.randomKeySTR();

        Random rand = new Random();
        int gold = confEgg.gold;
        Egg e = new Egg();
        e.gold = gold;
        e.kind = kindEgg;
        e.timeBirth = birh;

        String egg  =   Util.obj2String(e);
        
        if (Redis_W.getInstance().set(key, egg) == -1) {
            return "";
        }

        return key;
    }
    
    /*
    Add the key of egg to list egg type
    */
    public static Boolean addListEgg( String keyEggs, String eggType, String keyEgg ) {
        
        String keyType  =   keyEggs + eggType;
        
        if( Redis_Rd.getInstance().sismember(keyEggs, keyType) == 0 )
        {
            Redis_W.getInstance().sadd(keyEggs, keyType);
        }
        return Redis_W.getInstance().sadd( keyType, keyEgg ) != -1;
    }
    
    /*
    Add the keys of eggs to list egg type compatible
    */
    public static Boolean addListEggs( String keyEggs, Map<String, Set<String>> listKeyEggs ) {
        
        if( listKeyEggs.size() > 0 )
        {
            for( Map.Entry<String, Set<String>> entry : listKeyEggs.entrySet() )
            {
                String keyType  =   keyEggs + entry.getKey();

                if( Redis_Rd.getInstance().sismember(keyEggs, keyType) == 0 )
                {
                    Redis_W.getInstance().sadd(keyEggs, keyType);
                }

                String[] keys   = entry.getValue().toArray( new String[listKeyEggs.size()] );
                if( Redis_W.getInstance().sadd( keyType, keys ) == keys.length ) 
                {
                    System.out.println( "U_EggModel: addListEggs --> Add egg in comleted with " + keys.length );
                    // UNKNOWN
                }   
            }
        }
        
        return false;
    }

    /*
    Remove egg from database ( remove from list egg type )
    */
    public static Boolean removeEggDB( String keyListEgg, String eggType, String keyEgg ) {
        
        String keyType  =   keyListEgg + eggType;

        if( Redis_W.getInstance().srem( keyType, keyEgg ) != 1 )
        {
            System.out.println( "Not current member" );
            return false;
        }
        
        Set<String> eggs    =   Redis_Rd.getInstance().smember( keyType );
        // Type lack of member
        if( eggs == null || eggs.size() <= 0 )
        {
            Redis_W.getInstance().srem( keyListEgg, keyType );
        }
        
        return true;
    }
    
    /*
    Remove eggs from database ( remove from list egg type compatible )
    */
    public static Boolean removeEggDB( String keyListEgg, Map<String, Set<String>> keyEggs ) {
        
        for( Map.Entry<String, Set<String>> entry : keyEggs.entrySet())
        {
            String keyType  =   keyListEgg + entry.getKey();
            String[] eggStrs   =   new String[entry.getValue().size()];
            entry.getValue().toArray(eggStrs);

            if( Redis_W.getInstance().srem( keyType, eggStrs ) != 1 )
            {
                System.out.println( "Not current member" );
                return false;
            }

            Set<String> eggs    =   Redis_Rd.getInstance().smember( keyType );
            // Type lack of member
            if( eggs == null || eggs.size() <= 0 )
            {
                Redis_W.getInstance().srem( keyListEgg, keyType );
            }
        }
        
        return true;
    }
    
    /*
    Delete egg from database
    */
    public static Boolean delEggDB( String keyEgg ) {
        
        if( Redis_W.getInstance().del(keyEgg) != 1 ) {
            System.out.println( "Delete failed" );
            return false;
        }
        return true;
    }
    
    /*
    Delete multi-egg from database (delete value)
    */
    public static Boolean delEggDB( String[] keyEggs ) {
        
        if( Redis_W.getInstance().del(keyEggs) != keyEggs.length ) {
            System.out.println( "Delete failed" );
            return false;
        }
        return true;
    }
    
    /*
    Utilities
    Get the biggest time spawn of egg from a collection 
    */
    public static Egg lastestEgg( ArrayList<Egg> eggs )
    {
        Egg e   =   new Egg();
        if( eggs.size() > 0 )
        {
            long lastTime   =   eggs.get(0).timeBirth;
            for( Egg eit : eggs )
            {
                if( eit.timeBirth >= lastTime )
                    e   =   eit;
            }
        }
        return e;
    }
}
